﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml.Linq;

namespace XmlToSrt
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnBatch_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dialog = new FolderBrowserDialog())
            {
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    System.Net.WebClient webClient = new System.Net.WebClient();
                    if (!string.IsNullOrEmpty(txtProxy.Text))
                    {
                        string[] ss = txtProxy.Text.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                        try
                        {
                            webClient.Proxy = new System.Net.WebProxy(ss[0], Convert.ToInt32(ss[1]));
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("Proxy is invalid!", "Error!");
                        }
                    }
                    foreach (string fileName in System.IO.Directory.GetFiles(dialog.SelectedPath, "*.mp4", SearchOption.AllDirectories))
                    {
                        string path = System.IO.Path.GetDirectoryName(fileName);
                        string name = System.IO.Path.GetFileNameWithoutExtension(fileName);
                        string srtFileName = System.IO.Path.Combine(path, name + ".srt");
                        if (System.IO.File.Exists(srtFileName))
                            continue;

                        string xmlAddress = string.Format("http://s3.amazonaws.com/stanford_videos/cs229/subtitles/{0}-subtitles.xml", name);
                        //string xmlFileName = System.IO.Path.Combine(path, name + ".xml");
                        // string xmlTxt = File.ReadAllText(xmlFileName);
                        try
                        {
                            string xmlTxt = webClient.DownloadString(xmlAddress);

                            string srtTxt = this.ToSrt(xmlTxt);

                            File.WriteAllText(srtFileName, srtTxt);
                        }
                        catch (Exception exception)
                        {
                            MessageBox.Show(exception.Message, "Error!");
                        }
                    }
                }
            }
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(this.txtMain.Text))
                {
                    Clipboard.SetText(this.txtMain.Text);
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error!");
            }
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.txtMain.Text))
            {
                MessageBox.Show("Nothing to export", this.Text);
            }
            else
            {
                this.Export(this.txtMain.Text);
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*";
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    this.txtPath.Text = dialog.FileName;
                    this.Process(this.txtPath.Text);
                }
            }
        }

        private void Process(string path)
        {
            try
            {
                string xml = File.ReadAllText(path);
                this.txtMain.Text = this.ToSrt(xml);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error!");
            }
        }

        private void Export(string data)
        {
            using (System.Windows.Forms.SaveFileDialog dialog = new System.Windows.Forms.SaveFileDialog())
            {
                dialog.Filter = "Subtitle File (*.srt)|*.srt|All Files (*.*)|*.*";
                dialog.FileName = Path.GetFileNameWithoutExtension(this.txtPath.Text);
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    this.SaveFileDialog(dialog.FileName, data);
                }
            }
        }

        private string Purge(string input)
        {
            input = input.Replace("&lt;", "<").Replace("&gt;", ">");
            Regex regex = new Regex(@"<\s*/?\s*span[^>]*>");
            return regex.Replace(input, string.Empty).Trim();
        }

        private void SaveFileDialog(string path, string data)
        {
            try
            {
                File.WriteAllText(path, data);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error!");
            }
        }

        private string ToSrt(string xml)
        {
            XElement[] elementArray = XDocument.Parse(xml).Root.Element(XMLNames.body).Element(XMLNames.div).Elements(XMLNames.p).ToArray<XElement>();
            StringBuilder builder = new StringBuilder();
            int num = 1;
            foreach (XElement element in elementArray)
            {
                string s = element.Attribute(XMLNames.begin).Value.Trim();
                string str2 = element.Attribute(XMLNames.dur).Value.Trim();
                try
                {
                    TimeSpan span = TimeSpan.Zero, span2 = TimeSpan.Zero;

                    span = TimeSpan.Parse(s);
                    span2 = span + TimeSpan.Parse(str2);

                    builder.AppendLine(num.ToString());
                    builder.AppendFormat("{0:D2}:{1:D2}:{2:D2},{3:D3} --> {4:D2}:{5:D2}:{6:D2},{7:D3}", new object[] { span.Hours, span.Minutes, span.Seconds, span.Milliseconds, span2.Hours, span2.Minutes, span2.Seconds, span2.Milliseconds });
                    builder.AppendLine();
                    string str3 = this.Purge(element.Value);
                    builder.AppendLine(str3);
                    builder.AppendLine();
                    num++;
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message, "Error!");
                }
            }
            return builder.ToString();
        }

        private void txtMain_TextChanged(object sender, EventArgs e)
        {
            this.btnCopy.Enabled = this.btnExport.Enabled = !string.IsNullOrEmpty(this.txtMain.Text);
        }
    }
}
